﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Calendar;
using BLL;
using ZedGraph;

namespace UI
{
    public partial class FMain : Form
    {
        //日历项
        private List<CalendarItem> calItems = new List<CalendarItem>();
        public static AccountManagement accMan = new AccountManagement();
        public static RecordManagement rcdMan = new RecordManagement();
        public static TypeManagement typMan = new TypeManagement();
        private string strAccountID = "0";
        private struct statistic
        {
            public int iID;
            public double iAmount;
            public int iTimes;
        };
        public FMain()
        {
            InitializeComponent();
        }

        private void FMain_Load(object sender, EventArgs e)
        {
            //从XML文件读取数据
            accMan.LoadDataFromFile();
            typMan.LoadDataFromFile();
            rcdMan.LoadDataFromFile();
            LoadAccountToList();           
            LoadRecordToCalendar(rcdMan.RecordList);
            LoadRecordToGrid(rcdMan.RecordList, strAccountID);
        }


        private void 收支记录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FCreateRecord fcr = new FCreateRecord();
            fcr.ShowDialog();
            LoadRecordToGrid(rcdMan.RecordList, strAccountID);
        }

        private void toolStripButton_Online_Click(object sender, EventArgs e)
        {
            FGetOnline fgo = new FGetOnline();
            fgo.ShowDialog();
            LoadRecordToCalendar(rcdMan.RecordList);
            LoadRecordToGrid(rcdMan.RecordList, strAccountID);
        }

        private void toolStripButton_Statistics_Click(object sender, EventArgs e)
        {
            pl_Calendar.Visible = false;
            panel_Record.Visible = true;
            dgvRecord.Visible = false;
            splitContainer_Horizontal.Visible = true;
        }

        private void 收支类型ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FCreateType fct = new FCreateType();
            fct.ShowDialog();
        }

        private void 账户ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            FCreateAccount fca = new FCreateAccount();
            fca.ShowDialog();
            LoadAccountToList();

        }

        private void toolStripButton_Account_Click(object sender, EventArgs e)
        {
            FManageAccount fma = new FManageAccount();
            fma.ShowDialog();
            LoadAccountToList();
            LoadRecordToGrid(rcdMan.RecordList, strAccountID);
        }

        private void toolStripButton_View_Click(object sender, EventArgs e)
        {
            if (pl_Calendar.Visible)         //显示日程视图
            {
                pl_Calendar.Visible = false;
                panel_Record.Visible = true;
                dgvRecord.Visible = true;
                splitContainer_Horizontal.Visible = false;
            }
            else                          //显示日历视图
            {
                pl_Calendar.Visible = true;
                panel_Record.Visible = false;
                splitContainer_Horizontal.Visible = false;
            }
        }

        private void LoadRecordToCalendar(RecordCollection rc)
        {
            foreach (Record item in rc)
            {
                CalendarItem cal = new CalendarItem(calendar1, item.Time, item.Time.AddHours(1), typMan.GetType(item.TypeID).Name+"：￥"+ item.Amount.ToString("0.00")+"，"+item.Remark);
                int iColor=accMan.GetAccount(item.AccountID).Color;
                if (iColor!=0)
                {
                    cal.ApplyColor(Color.FromArgb(iColor));
                }
                calItems.Add(cal);
                if (calendar1.ViewIntersects(cal))
                {
                    calendar1.Items.Add(cal);
                }

            }
        }

        private void calendar1_LoadItems(object sender, CalendarLoadEventArgs e)
        {
            LoadRecordToCalendar(rcdMan.RecordList);
        }

        private void calendar1_DayHeaderClick(object sender, CalendarDayEventArgs e)
        {
            if (calendar1.DaysMode == CalendarDaysMode.Short)
            {
                calendar1.SetViewRange(e.CalendarDay.Date, e.CalendarDay.Date);
            }
            else
            {
                calendar1.SetViewRange(e.CalendarDay.Date.AddDays(-21), e.CalendarDay.Date);
            }
        }

        private void LoadAccountToList()
        {
            lvAccount.Items.Clear();
            //生成"全部"项

            ListViewItem lv= new ListViewItem(new string[]{"全部","0"},-1,Color.Black,Color.Empty,new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point, ((System.Byte)(0))));
            lvAccount.Items.Add(lv);
            //读取XML数据
            for (int i = 0; i < accMan.AccountList.Count; i++)
            {
                string[] item = { accMan.AccountList[i].Name, accMan.AccountList[i].ID.ToString() };
                ListViewItem lvi = new ListViewItem(item, -1, Color.FromArgb(accMan.AccountList[i].Color), Color.Empty, new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point, ((System.Byte)(0))));
                lvAccount.Items.Add(lvi);
            }
            lvAccount.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        }

        private void lvAccount_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvAccount.SelectedIndices != null && lvAccount.SelectedIndices.Count > 0)
            {
                strAccountID = lvAccount.SelectedItems[0].SubItems[1].Text;

                LoadRecordToGrid(rcdMan.RecordList, strAccountID);
            }
            
        }

        private void toolStripButton_Type_Click(object sender, EventArgs e)
        {
            FManageType f = new FManageType();
            f.ShowDialog();
        }

        private void LoadRecordToGrid(RecordCollection recList,string strID) 
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("ID"));
            dt.Columns.Add(new DataColumn("Time"));
            dt.Columns.Add(new DataColumn("Type"));
            dt.Columns.Add(new DataColumn("Account"));
            dt.Columns.Add(new DataColumn(("Amount"), System.Type.GetType("System.Double")));    
            dt.Columns.Add(new DataColumn("Remark"));
            for (int i = 0; i < recList.Count; i++)
            {
                if (recList[i].AccountID.ToString() == strID || strID == "0")
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = recList[i].ID;
                    dr[1] = recList[i].Time.ToString("yyyy-MM-dd");
                    if (typMan.GetType(recList[i].TypeID) != null)
                    {
                        dr[2] = typMan.GetType(recList[i].TypeID).Name;
                    }
                    else
                    {
                        dr[2] = null;
                    }
                    if (accMan.GetAccount(recList[i].AccountID) != null)
                    {
                        dr[3] = accMan.GetAccount(recList[i].AccountID).Name;
                    }
                    else
                    {
                        dr[3] = null;
                    }
                    dr[4] = recList[i].Amount;
                    dr[5] = recList[i].Remark;
                    dt.Rows.Add(dr);
                }
            }
            //实现datagridview按时间降序排列
            DataView dv = new DataView(dt);
            dv.Sort = "Time desc";
            dgvRecord.DataSource = dv;
            

        }

        private void CreateGraph(ZedGraphControl zg)
        {
            DateTime dtF = dtpFrom.Value;
            DateTime dtT = dtpTo.Value;
            bool Isincome;
            bool Istype;
            if (rbIsIncome.Checked)
            {
                Isincome = true; //测试用，实际使用时“按收入统计”为true
            }
            else
            {
                Isincome = false; //测试用，实际使用时“按收入统计”为true
            }
            if (rbAccount.Checked)
            {
                Istype = false; //测试用，实际使用时“按类型统计”为true
            }
            else
            {
                Istype = true;
            }
            zg.GraphPane.CurveList.Clear();
            zg.Refresh();
            GraphPane myPane = zg.GraphPane;  
            //SetDataSource
            ArrayList alStatistic = GetStatisticResult(dtF, dtT, Isincome, Istype);
            if (alStatistic.Count != 1)
            {
                for (int i = 0; i < alStatistic.Count - 1; i++)
                {
                    statistic sta = new statistic();
                    sta = (statistic)alStatistic[i];
                    if (!Istype)
                    {
                        // Set the Titles
                        myPane.Title.Text = dtF.ToString("yyyy-MM-dd ") + "至" + dtT.ToString("yyyy-MM-dd ") + "按账户统计结果";
                        myPane.Title.FontSpec = new ZedGraph.FontSpec("微软雅黑",15, Color.Black, false, false, false);
                        PieItem myPie = myPane.AddPieSlice(sta.iAmount, Color.FromArgb((FMain.accMan.GetAccount(sta.iID)).Color), 0.1, FMain.accMan.GetAccount(sta.iID).Name.ToString());
                        myPie.Fill = new Fill(Color.FromArgb((FMain.accMan.GetAccount(sta.iID)).Color), Color.White, Color.FromArgb((FMain.accMan.GetAccount(sta.iID)).Color));
                    }
                    else     //Type类型没有颜色，就随机生成颜色了
                    {
                        // Set the Titles
                        myPane.Title.Text = dtF.ToString("yyyy-MM-dd ") + "至" + dtF.ToString("yyyy-MM-dd ") + "按类型统计结果";
                        Random RandomNum = new Random((int)DateTime.Now.Ticks);
                        PieItem myPie = myPane.AddPieSlice(sta.iAmount, Color.Blue, 0.1, FMain.typMan.GetType(sta.iID).Name.ToString());
                        myPie.Fill = new Fill(Color.FromArgb(RandomNum.Next(-999999999,999999999)), Color.White, Color.FromArgb(RandomNum.Next(-999999999,999999999)));
                        System.Threading.Thread.Sleep(RandomNum.Next(50));
                    }
                }
                //            myPane.Legend.Position = LegendPos.Float;
                //            myPane.Legend.Location = new Location(0.95f, 0.15f, CoordType.PaneFraction, AlignH.Right, AlignV.Top);
                myPane.Legend.IsHStack = true;
                myPane.Legend.FontSpec.Border = new ZedGraph.Border(false, Color.Black, 1);
                // Fill the Axis and Pane backgrounds
                myPane.Chart.Fill = new Fill(Color.White, Color.FromArgb(255, 255, 166), 90F);
                myPane.Fill = new Fill(Color.FromArgb(250, 250, 255));
                // Tell ZedGraph to refigure the axes since the data have changed
                zg.AxisChange();
                zg.Visible = true;
                lblInfo.Visible = false;
            }
            else
            {
                zg.Visible = false;
                lblInfo.Text = "Sorry, no valid data";
                lblInfo.Visible = true;
            }
        }

        ///<param name="dtF" 起始时间></param>
        ///<param name="dtT" 结束时间></param>
        ///<param name="Isincome" 按收入统计为true></param>
        ///<param name="IsType" 按类型统计为true></param>
        private ArrayList GetStatisticResult(DateTime dtF, DateTime dtT, bool Isincome, bool IsType)
        {
            ArrayList statisticList = new ArrayList();
            double iTotalAmount = 0;
            foreach (Record record in FMain.rcdMan.RecordList)
            {
                if (Isincome == FMain.typMan.GetType(record.TypeID).Isincome && dtF <= record.Time && record.Time <= dtT)  //判断Record条目的收支类型是否与用户的选择相同，且时间段相同
                {
                    if (IsType)   //如果按类型统计
                    {
                        if (IsExist(statisticList, record.TypeID) == -1) //statisticList中不存在该Type，则添加该Type
                        {
                            statistic sta = new statistic();
                            sta.iID = record.TypeID;
                            sta.iAmount = 0;
                            sta.iAmount += record.Amount;
                            sta.iTimes = 1;
                            statisticList.Add(sta);
                            iTotalAmount += record.Amount;
                        }
                        else  //否则，该Type已经存在，更新该Type的总金额
                        {
                            statistic sta = new statistic();
                            sta = (statistic)statisticList[IsExist(statisticList, record.TypeID)];
                            sta.iAmount += record.Amount;
                            sta.iTimes += 1;
                            statisticList[IsExist(statisticList, record.TypeID)] = sta;
                            iTotalAmount += record.Amount;
                        }
                    }
                    else    //如果按账户统计
                    {
                        if (IsExist(statisticList, record.AccountID) == -1) //statisticList中不存在该Account，则添加该Account
                        {
                            statistic sta = new statistic();
                            sta.iID = record.AccountID;
                            sta.iAmount = 0;
                            sta.iAmount += record.Amount;
                            sta.iTimes = 1;
                            statisticList.Add(sta);
                            iTotalAmount += record.Amount;
                        }
                        else  //否则，该Account已经存在，更新该Account的总金额
                        {
                            statistic sta = new statistic();
                            sta = (statistic)statisticList[IsExist(statisticList, record.AccountID)];
                            sta.iAmount += record.Amount;
                            sta.iTimes += 1;
                            statisticList[IsExist(statisticList, record.AccountID)] = sta;
                            iTotalAmount += record.Amount;
                        }
                    }
                }
            }
            statisticList.Add(iTotalAmount);
            return statisticList;
        }

        private int IsExist(ArrayList statisticList, int iID)
        {
            for (int i = 0; i < statisticList.Count; i++)
            {
                statistic stat = (statistic)statisticList[i];
                if (stat.iID == iID)
                {
                    return i;
                }
            }
            return -1;
        }

        private void gvLoadData()
        {
            DateTime dtF = dtpFrom.Value;
            DateTime dtT = dtpTo.Value;
            bool Isincome;
            bool Istype;
            if (rbIsIncome.Checked)
            {
                Isincome = true; //测试用，实际使用时“按收入统计”为true
            }
            else
            {
                Isincome = false; //测试用，实际使用时“按收入统计”为true
            }
            if (rbAccount.Checked)
            {
                Istype = false; //测试用，实际使用时“按类型统计”为true
            }
            else
            {
                Istype = true;
            }
            //SetDataSource
            ArrayList alStatistic = GetStatisticResult(dtF, dtT, Isincome, Istype);
            double iTotalAmount = (double)alStatistic[(alStatistic.Count) - 1];
            DataTable dt = new DataTable();
            DataColumn dc0 = new DataColumn("Name");
            DataColumn dc1 = new DataColumn("Amount",typeof(decimal));
            DataColumn dc2 = new DataColumn("Percentage",typeof(decimal));
            DataColumn dc3 = new DataColumn("Times");
            dt.Columns.Add(dc0);
            dt.Columns.Add(dc1);
            dt.Columns.Add(dc2);
            dt.Columns.Add(dc3);
            for (int i = 0; i < alStatistic.Count - 1; i++)
            {
                statistic sta = new statistic();
                sta = (statistic)alStatistic[i];
                DataRow dr = dt.NewRow();
                dr[1] = sta.iAmount;
                dr[2] = (sta.iAmount) / iTotalAmount;
                dr[3] = sta.iTimes;
                dt.Rows.Add(dr);
                if (!Istype)
                {
                    dr[0] = FMain.accMan.GetAccount(sta.iID).Name;
                }
                else
                {
                    dr[0] = FMain.typMan.GetType(sta.iID).Name;
                }
            }
            gvStatistic.DataSource = dt;   //说明：gvType的属性为只读，整行选取，每次只能选中一行
        }

        private void 修改记录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iRowNo = Convert.ToInt32(dgvRecord.SelectedRows[0].Index);
            FCreateRecord fcr = new FCreateRecord(Convert.ToInt32(dgvRecord.Rows[iRowNo].Cells[0].Value));
            fcr.ShowDialog();
            LoadRecordToGrid(rcdMan.RecordList,strAccountID);
            dgvRecord.Rows[iRowNo].Selected = true;
        }

        private void 删除记录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iRecordID = Convert.ToInt32(dgvRecord.SelectedRows[0].Cells[0].Value);
            BLL.Record rec=new Record();
            rec=FMain.rcdMan.GetRecord(iRecordID);
            BLL.Type typ = new BLL.Type();
            typ = FMain.typMan.GetType(rec.TypeID);
            int iIndex=FMain.accMan.GetAccountIndex(rec.AccountID);  //获取该Record对应Account在AccountList中的索引值
            if (typ.Isincome)
            {
                FMain.accMan.AccountList[iIndex].Balance -= rec.Amount;   //若为收入，则删除该记录后该索引值对应Account的余额应该减少
            }
            else
            {
                FMain.accMan.AccountList[iIndex].Balance += rec.Amount;   //若为支出，则删除该记录后该索引值对应Account的余额应该增加
            } 
            FMain.accMan.SaveDataToFile();  //保存更改至account.xml文件
            rcdMan.DelRecord(iRecordID);       //删除Record 
            LoadRecordToGrid(rcdMan.RecordList, strAccountID);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CreateGraph(zg);
            gvLoadData();
            tabControl.SelectedTab=tabPage_Sheet;
        }      
    }
}
